package bid.yanhj.common.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import bid.yanhj.common.util.MetaInfo;

/**
 * 日志格式化类.
 * 
 * @author yanhaijiang
 *
 */
public final class FormatService {
	/**
	 * log.
	 */
	private static final Logger LOG = LoggerFactory.getLogger(FormatService.class);

	/**
	 * enum.
	 * 
	 * @author yanhaijiang
	 *
	 */
	public static enum LOGSTEP {
		/**
		 * TYPE.
		 */
		SUCCESS, FAILED, DEFAULT
	}
    /**
     * json mapper.
     */
    private static ObjectMapper mapper = new ObjectMapper();
    /**
     * tag.
     */
    private static final String STATUS_SUE = "SUE";
    /**
     * tag.
     */
    private static final String STATUS_FAD = "FAD";
    /**
     * tag.
     */
    private static final String PROCESS = "[PROCESS]";
    /**
     * tag.
     */
    private static final String L = "[";
    /**
     * tag.
     */
    private static final String R = "]";
    /**
     * tag.
     */
    private static final String RL = "][";
    /**
     * tag.
     */
    private static final String TIME_MS = "ms";
    /**
     * tag.
     */
    private static final String PRM = "[PRM=";
    /**
     * tag.
     */
    private static final String RTN = "[RTN=";

    /***/
    private static final String LID = "LID=";
    /***/
    private static final String BID = "BID=";
    /***/
    private static final String ETM = "ETM=";
    /**
     * tag.
     */
    private static final String MSG = "[MSG=";
    /**
     * tag.
     */
    private static final String ACC = "[ACC-";
    /**
     * tag.
     */
    private static final String XR = "]";
    /**
     * tag.
     */
    private static final String TXR = "...]";

    /**
     * tag.
     */
    private static final String BLANK = "";
    /**
     * tag.
     */
    private static final int LENGTH_MAX = 4096;

    /**
     * Constructor.
     */
    private FormatService() {

    }
    
    /**
     * 将信息标记到本次访问线程中，信息将打印在本次访问的访问日志中.
     * 
     * @param step type
     */
    public static void accMark(LOGSTEP step) {
		if (step != null) {
			MetaInfo meta = getMetaInfo();
			if (meta != null && LOGSTEP.SUCCESS == step) {
				meta.setStatus(STATUS_SUE);
			} else if (meta != null && LOGSTEP.FAILED == step) {
                meta.setStatus(STATUS_FAD);
            }
		}
	}
    
    /**
     * 格式化日志.
     * 
     * @param msg message
     * @return String
     */
    public static String logFormat(String msg) {
    	String message = BLANK;
        if (msg != null) {
            message = msg;
        }
        MetaInfo meta = getMetaInfo();
        StringBuffer buffer = new StringBuffer();
        buffer.append(PROCESS);
        buffer.append(L).append(LID).append(meta.getUuid()).append(RL);
        buffer.append(BID).append(meta.getBid()).append(RL);
        long time = meta.getFtime();
        buffer.append(ETM).append(time).append(TIME_MS);
        buffer.append(RL).append(meta.getMethod()).append(R);
        buffer.append(MSG).append(message).append(XR);
        return buffer.toString();
    }

    /**
     * 格式化访问日志，仅供拦截器中调用.
     * 
     * @param param object
     * @return String
     */
    public static String accFormat(Object param) {
        Object paramObj = BLANK;
        if (param != null) {
            paramObj = param;
        }
        Object returnObj = CacheService.getResult();
        if (returnObj == null) {
            returnObj = BLANK;
        } else {
            try {
                returnObj = mapper.writeValueAsString(returnObj);
            } catch (JsonProcessingException e) {
                LOG.error("json mapper error " + e.getMessage());
            }
        }
        MetaInfo meta = getMetaInfo();
        StringBuffer buffer = new StringBuffer();
        buffer.append(ACC).append(meta.getStatus()).append(R);
        buffer.append(L).append(LID).append(meta.getUuid()).append(RL);
        buffer.append(BID).append(meta.getBid()).append(RL);
        long time = meta.getFtime();
        buffer.append(ETM).append(time).append(TIME_MS);
        buffer.append(RL).append(meta.getMethod()).append(R);
        buffer.append(MSG).append(XR);
        String paramString = paramObj.toString();
        String returnString = returnObj.toString();
        if (paramString.length() <= LENGTH_MAX) {
            buffer.append(PRM).append(paramString).append(XR);
        } else {
            buffer.append(PRM).append(paramString.substring(0, LENGTH_MAX)).append(TXR);
        }
        if (returnString.length() <= LENGTH_MAX) {
            buffer.append(RTN).append(returnString).append(XR);
        } else {
            buffer.append(RTN).append(returnString.substring(0, LENGTH_MAX)).append(TXR);
        }
        return buffer.toString();
    }

    /**
     * getMetaInfo.
     * 
     * @return MetaInfo
     */
    private static MetaInfo getMetaInfo() {
        MetaInfo meta = CacheService.getMetaInfo();
        if (meta == null) {
            init(BLANK);
            meta = CacheService.getMetaInfo();
        }
        return meta;
    }

    /**
     * init.
     * 
     * @param method httprequestURI
     */
    public static void init(String method) {
        MetaInfo info = new MetaInfo(method);
        CacheService.putMetaInfo(info);
    }
}